package it.unicam.cs.cosy.bioshape.gui.visualizer3d;

import java.text.DecimalFormat;

import javax.media.j3d.Behavior;
import javax.media.j3d.WakeupCondition;
import javax.media.j3d.WakeupCriterion;
import javax.media.j3d.WakeupOnElapsedFrames;

/**
 * Implements a simple {@code Behavior} to show the fps (frame per second) of
 * the simulation.
 * 
 * @author Federico Buti
 */
public class FpsBehavior extends Behavior {
	// the wake up condition for the behavior
	protected WakeupCondition m_WakeupCondition = null;
	protected long m_StartTime = 0;
	private final int m_knReportInterval = 5;
	private double fps;
	private VisualizationPanel panel;
	private DecimalFormat f;

	/**
	 * Builds the {@code Behaviour}.
	 * 
	 * @param visualizationPanel
	 *            reference to the main window of the visualiser
	 */
	public FpsBehavior(VisualizationPanel visualizationPanel) {
		m_WakeupCondition = new WakeupOnElapsedFrames(m_knReportInterval);
		panel = visualizationPanel;
		f = new DecimalFormat(".0000");
	}

	@Override
	public void initialize() {
		// apply the initial WakeupCriterion
		wakeupOn(m_WakeupCondition);
	}

	@Override
	@SuppressWarnings("rawtypes")
	public void processStimulus(java.util.Enumeration criteria) {
		
		while (criteria.hasMoreElements()) {
			WakeupCriterion wakeUp = (WakeupCriterion) criteria.nextElement();
			// every N frames, report the FPS
			if (wakeUp instanceof WakeupOnElapsedFrames) {
				if (m_StartTime > 0) {
					final long interval = System.currentTimeMillis()
							- m_StartTime;
					fps = m_knReportInterval / (interval / 1000.0);
					String fpS = f.format(fps);
					panel.setFPS(fpS);
				}
				m_StartTime = System.currentTimeMillis();
			}
		}
		// assign the next WakeUpCondition, so we are notified again
		wakeupOn(m_WakeupCondition);
	}
}